/******************************************************************************
秋夜静，独坐对残灯。
啼笑非非谁识我，坐行梦梦尽缘君，何所慰消沉。
风卷雨，雨复卷侬心。
心似欲随风雨去，茫茫大海任浮沉。
无爱亦无恨。
******************************************************************************/
#include "kbRGB_Angle.h"
#include <stdio.h>
#include <math.h>

static const uint32_t RotateMatrixAngle[KBRGB_ANGLE_SIZE][KBRGB_ANGLE_SIZE] = {
{0x00000000, 0x01000000, 0x02000000, 0x03000000, 0x04000000, 0x05000000, 0x06000000, 0x07000000, 0x08000000, 0x09000000, 0x0A000000, 0x0B000000, 0x0C000000, 0x0D000000, 0x0E000000, 0x0F000000, 0x10000000, 0x11000000, 0x12000000, 0x13000000, 0x14000000},
{0x010002CF, 0x016A0167, 0x023C00D4, 0x03290093, 0x041F0070, 0x0519005A, 0x0615004B, 0x07120041, 0x080F0039, 0x090E0032, 0x0A0C002D, 0x0B0B0029, 0x0C0A0026, 0x0D090023, 0x0E090020, 0x0F08001E, 0x1007001C, 0x1107001A, 0x12070019, 0x13060018, 0x14060016},
{0x020002CF, 0x023C01FB, 0x02D40167, 0x039B010D, 0x047800D4, 0x056200AE, 0x06530093, 0x0747007F, 0x083F0070, 0x09380064, 0x0A32005A, 0x0B2E0052, 0x0C2A004B, 0x0D270045, 0x0E240041, 0x0F21003C, 0x101F0039, 0x111E0035, 0x121C0032, 0x131A0030, 0x1419002D},
{0x030002CF, 0x0329023C, 0x039B01C2, 0x043E0167, 0x05000126, 0x05D400F7, 0x06B500D4, 0x079D00B9, 0x088B00A4, 0x097C0093, 0x0A700085, 0x0B66007A, 0x0C5E0070, 0x0D570067, 0x0E510060, 0x0F4C005A, 0x10470054, 0x11430050, 0x123F004B, 0x133C0047, 0x14390044},
{0x040002CF, 0x041F025F, 0x047801FB, 0x050001A9, 0x05A80167, 0x06670135, 0x0736010D, 0x080F00ED, 0x08F100D4, 0x09D900BF, 0x0AC500AE, 0x0BB4009F, 0x0CA60093, 0x0D990088, 0x0E8F007F, 0x0F860077, 0x107E0070, 0x11760069, 0x12700064, 0x136A005F, 0x1465005A},
{0x050002CF, 0x05190275, 0x05620221, 0x05D401D8, 0x0667019A, 0x07120167, 0x07CF013E, 0x089A011C, 0x096F0100, 0x0A4B00E8, 0x0B2E00D4, 0x0C1500C3, 0x0D0000B4, 0x0DED00A8, 0x0EDD009D, 0x0FCF0093, 0x10C3008A, 0x11B80083, 0x12AE007C, 0x13A50075, 0x149D0070},
{0x060002CF, 0x06150284, 0x0653023C, 0x06B501FB, 0x073601C2, 0x07CF0191, 0x087C0167, 0x09380144, 0x0A000126, 0x0AD1010D, 0x0BA900F7, 0x0C8700E4, 0x0D6A00D4, 0x0E5100C6, 0x0F3B00B9, 0x102700AE, 0x111600A4, 0x1207009B, 0x12F90093, 0x13EC008C, 0x14E10085},
{0x070002CF, 0x0712028E, 0x07470250, 0x079D0216, 0x080F01E2, 0x089A01B3, 0x0938018B, 0x09E60167, 0x0AA10149, 0x0B66012E, 0x0C340117, 0x0D090103, 0x0DE400F2, 0x0EC300E2, 0x0FA700D4, 0x108D00C8, 0x117600BD, 0x126200B3, 0x135000AA, 0x143F00A1, 0x1530009A},
{0x080002CF, 0x080F0296, 0x083F025F, 0x088B022B, 0x08F101FB, 0x096F01CF, 0x0A0001A9, 0x0AA10186, 0x0B500167, 0x0C0A014D, 0x0CCE0135, 0x0D990120, 0x0E6C010D, 0x0F4300FC, 0x101F00ED, 0x110000E0, 0x11E300D4, 0x12C900C9, 0x13B200BF, 0x149D00B6, 0x158A00AE},
{0x090002CF, 0x090E029D, 0x0938026B, 0x097C023C, 0x09D90210, 0x0A4B01E7, 0x0AD101C2, 0x0B6601A1, 0x0C0A0182, 0x0CBA0167, 0x0D74014F, 0x0E36013A, 0x0F000126, 0x0FCF0115, 0x10A40105, 0x117E00F7, 0x125B00EA, 0x133C00DF, 0x141F00D4, 0x150600CA, 0x15EE00C1},
{0x0A0002CF, 0x0A0C02A2, 0x0A320275, 0x0A70024A, 0x0AC50221, 0x0B2E01FB, 0x0BA901D8, 0x0C3401B8, 0x0CCE019A, 0x0D740180, 0x0E240167, 0x0EDD0152, 0x0F9E013E, 0x1066012C, 0x1134011C, 0x1207010D, 0x12DE0100, 0x13B900F3, 0x149700E8, 0x157800DE, 0x165C00D4},
{0x0B0002CF, 0x0B0B02A6, 0x0B2E027D, 0x0B660255, 0x0BB40230, 0x0C15020C, 0x0C8701EB, 0x0D0901CC, 0x0D9901AF, 0x0E360195, 0x0EDD017D, 0x0F8E0167, 0x10470154, 0x11070141, 0x11CD0131, 0x12990122, 0x136A0114, 0x143F0107, 0x151800FB, 0x15F400F0, 0x16D300E6},
{0x0C0002CF, 0x0C0A02A9, 0x0C2A0284, 0x0C5E025F, 0x0CA6023C, 0x0D00021B, 0x0D6A01FB, 0x0DE401DD, 0x0E6C01C2, 0x0F0001A9, 0x0F9E0191, 0x1047017B, 0x10F80167, 0x11B10155, 0x12700144, 0x13350135, 0x14000126, 0x14CF0119, 0x15A2010D, 0x16780102, 0x175200F7},
{0x0D0002CF, 0x0D0902AC, 0x0D27028A, 0x0D570268, 0x0D990247, 0x0DED0227, 0x0E510209, 0x0EC301ED, 0x0F4301D3, 0x0FCF01BA, 0x106601A3, 0x1107018E, 0x11B1017A, 0x12620167, 0x131A0157, 0x13D90147, 0x149D0138, 0x1566012B, 0x1634011E, 0x17050113, 0x17DA0108},
{0x0E0002CF, 0x0E0902AF, 0x0E24028E, 0x0E51026F, 0x0E8F0250, 0x0EDD0232, 0x0F3B0216, 0x0FA701FB, 0x101F01E2, 0x10A401CA, 0x113401B3, 0x11CD019E, 0x1270018B, 0x131A0178, 0x13CC0167, 0x14840158, 0x15420149, 0x1605013B, 0x16CD012E, 0x17990123, 0x18690117},
{0x0F0002CF, 0x0F0802B1, 0x0F210293, 0x0F4C0275, 0x0F860258, 0x0FCF023C, 0x10270221, 0x108D0207, 0x110001EF, 0x117E01D8, 0x120701C2, 0x129901AD, 0x1335019A, 0x13D90188, 0x14840177, 0x15360167, 0x15EE0159, 0x16AB014B, 0x176E013E, 0x18350132, 0x19000126},
{0x100002CF, 0x100702B3, 0x101F0296, 0x1047027B, 0x107E025F, 0x10C30245, 0x1116022B, 0x11760212, 0x11E301FB, 0x125B01E5, 0x12DE01CF, 0x136A01BB, 0x140001A9, 0x149D0197, 0x15420186, 0x15EE0176, 0x16A00167, 0x1758015A, 0x1815014D, 0x18D60140, 0x199C0135},
{0x110002CF, 0x110702B5, 0x111E029A, 0x1143027F, 0x11760266, 0x11B8024C, 0x12070234, 0x1262021C, 0x12C90206, 0x133C01F0, 0x13B901DC, 0x143F01C8, 0x14CF01B6, 0x156601A4, 0x16050194, 0x16AB0184, 0x17580175, 0x180A0167, 0x18C2015A, 0x197E014E, 0x1A3F0142},
{0x120002CF, 0x120702B6, 0x121C029D, 0x123F0284, 0x1270026B, 0x12AE0253, 0x12F9023C, 0x13500225, 0x13B20210, 0x141F01FB, 0x149701E7, 0x151801D4, 0x15A201C2, 0x163401B1, 0x16CD01A1, 0x176E0191, 0x18150182, 0x18C20175, 0x19740167, 0x1A2C015B, 0x1AE8014F},
{0x130002CF, 0x130602B7, 0x131A029F, 0x133C0288, 0x136A0270, 0x13A5025A, 0x13EC0243, 0x143F022E, 0x149D0219, 0x15060205, 0x157801F1, 0x15F401DF, 0x167801CD, 0x170501BC, 0x179901AC, 0x1835019D, 0x18D6018F, 0x197E0181, 0x1A2C0174, 0x1ADE0167, 0x1B96015C},
{0x140002CF, 0x140602B9, 0x141902A2, 0x1439028B, 0x14650275, 0x149D025F, 0x14E1024A, 0x15300235, 0x158A0221, 0x15EE020E, 0x165C01FB, 0x16D301E9, 0x175201D8, 0x17DA01C7, 0x186901B8, 0x190001A9, 0x199C019A, 0x1A3F018D, 0x1AE80180, 0x1B960173, 0x1C480167},
};

// 此处通过 uint32_t 返回数据由于数据丢失会产生奇特的效果
static uint32_t _kbRGB_Angle(float x, float y, float cx, float cy)
{
    double angle    = (atan2(x - cx, y - cy)) * 180 / 3.14159265359;
    double distance = sqrt(pow(cx - x, 2) + pow(cy - y, 2));

    struct kbRGB_Pixel piont;
    const float kbRGB_angls_pre = (float)(0x1<<KBRGB_ANGLE_PRE);
    const float kbRGB_radius_pre = (float)(0x1<<8);
    piont.angle = (uint16_t)(angle*kbRGB_angls_pre);     // 90*8 = 720:10bit[1024]
    piont.radius = (uint16_t)(distance*kbRGB_radius_pre); // sqrt(21*21)*2 = 29.7*256 < 16bit
    return piont.pixel;
}
/*************************************************************************************************
* 为节省空间占用,仅计算 0-90°范围,其它角度根据象限间的关系重新计算
* 为节保留 精度并加快运算速度,将处理后的结果保存为整型，精度为 1/64
**************************************************************************************************/
static void kbRGB_Angle(const uint16_t cols, const uint16_t rows)
{
    float cx = 0;//(cols - 1) * 0.5;
    float cy = 0;//(rows - 1) * 0.5;
    struct kbRGB_Pixel matrix[128][128];
    for (uint32_t col_id = 0; col_id < cols; col_id++)
    {
        for (uint32_t row_id = 0; row_id < rows; row_id++)
        {
            matrix[col_id][row_id].pixel = _kbRGB_Angle(col_id, row_id, cx, cy);
        }
    }
    //printf("const uint16_t RotateMatrix[%d][%d] = {\r\n", MATRIX_SIZE, MATRIX_SIZE);
    //printf("const uint16_t RotateMatrixAngle[MATRIX_SIZE][MATRIX_SIZE] = {\r\n");
    //printf("const uint32_t RotateMatrixAngle[%d][%d] = {\r\n", cols, rows);
    printf("static const uint32_t RotateMatrixAngle[KBRGB_ANGLE_SIZE][KBRGB_ANGLE_SIZE] = {\r\n");
    for(int y=0; y<rows; y++)
    {
        printf("{");
        for(int x=0; x<cols; x++)
        {
            //printf("%4d, ",  (int)matrix[y][x].angle);
            printf("0x%08X",  matrix[y][x].pixel);
            if(x<(cols-1)) printf(", ");
        }
        printf("},\r\n");
    }
    printf("};\r\n");
#if 0
    printf("static const uint16_t angle[MATRIX_ANGLE_SIZE][MATRIX_ANGLE_SIZE] = {\r\n");
    for(int y=0; y<rows; y++)
    {
        printf("{");
        for(int x=0; x<cols; x++)
        {
            //printf("%4d, ",  (int)matrix[y][x].angle);
            printf("%3d, ",  matrix[y][x].angle);
        }
        printf("},\r\n");
    }
    printf("};\r\n");
    printf("static const uint16_t radius[MATRIX_ANGLE_SIZE][MATRIX_ANGLE_SIZE] = {\r\n");
    for(int y=0; y<rows; y++)
    {
        printf("{");
        for(int x=0; x<cols; x++)
        {
            //printf("%4d, ",  (int)matrix[y][x].angle);
            printf("%3d, ",  matrix[y][x].radius);
        }
        printf("},\r\n");
    }
    printf("};\r\n");
#endif
    fflush(stdout);
}
void kbRGB_Angle8bit(void)
{
    kbRGB_Angle(KBRGB_ANGLE_SIZE, KBRGB_ANGLE_SIZE);
}
uint32_t kbRGB_Angle_8bitGet(const int16_t x, const int16_t y)
{
    struct kbRGB_Pixel piont = {.angle=0, .radius=0xFFFF};
    if((x>=KBRGB_ANGLE_SIZE) || (x<=-KBRGB_ANGLE_SIZE)) return piont.pixel;
    if((y>=KBRGB_ANGLE_SIZE) || (y<=-KBRGB_ANGLE_SIZE)) return piont.pixel;
    if((x>=0) && (y>=0)) // 第一象限
    {
        piont.pixel = RotateMatrixAngle[y][x];
    }
    if((x<0) && (y>=0)) // 第二象限
    {
        piont.pixel = RotateMatrixAngle[y][-x];
        //piont.angle = (uint32_t)(180*8) - piont.angle;
        piont.angle = ((uint32_t)180<<KBRGB_ANGLE_PRE) - piont.angle;
    }
    if((x<0) && (y<0)) // 第三象限
    {
        piont.pixel = RotateMatrixAngle[-y][-x];
        //piont.angle = (uint32_t)(180*8) + piont.angle;
        piont.angle = ((uint32_t)180<<KBRGB_ANGLE_PRE) + piont.angle;
    }
    if((x>=0) && (y<0)) // 第四象限
    {
        piont.pixel = RotateMatrixAngle[-y][x];
        //piont.angle = (uint32_t)(360*8) - piont.angle;
        piont.angle = ((uint32_t)360<<KBRGB_ANGLE_PRE) - piont.angle;
    }
    return piont.pixel;
}
